package com.mrzhou.user.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.mrzhou.common.constant.RoleConstant;
import com.mrzhou.common.entity.system.User;
import com.mrzhou.common.enums.MailPhoneType;
import com.mrzhou.common.feign.client.ISystemClient;
import com.mrzhou.common.util.ValidUtil;
import com.mrzhou.core.tool.api.CloudUser;
import com.mrzhou.core.tool.api.R;
import com.mrzhou.core.tool.utils.BeanUtil;
import com.mrzhou.core.tool.utils.DigestUtil;
import com.mrzhou.core.tool.utils.Func;
import com.mrzhou.data.annotation.RedisLock;
import com.mrzhou.data.util.CacheUtil;
import com.mrzhou.msg.feign.client.IMsgClient;
import com.mrzhou.msg.vo.req.ValidMailPhoneReq;
import com.mrzhou.system.cache.SystemCache;
import com.mrzhou.user.prop.UserProperties;
import com.mrzhou.user.service.IUserService;
import com.mrzhou.user.vo.UserSetting;
import com.mrzhou.user.vo.UserVO;
import com.mrzhou.web.secure.annotation.BeforeAuth;
import com.mrzhou.web.util.WebUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author qiang.zhou
 */
@RestController
@Api(value = "用户接口", tags = "用户接口")
public class UserController {

    @Autowired
    private IUserService userService;
    @Autowired
    private IMsgClient msgClient;
    @Autowired
    private UserProperties userProperties;
    @Autowired
    private ISystemClient systemClient;

    @GetMapping("/user-phone")
    @ApiOperation("根据注册账号查询用户信息")
    public R<User> queryUser(String account) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(User::getAccount, account);
        return R.data(userService.getOne(wrapper));
    }

    @PostMapping("/user-register")
    @ApiOperation("邮箱快捷注册")
    public R<String> registerUser(@ApiParam(value = "用户邮箱", required = true) @RequestParam(value = "mail") String mail,
                                  @ApiParam(value = "邮箱验证码", required = true) @RequestParam(value = "mailCode") String mailCode,
                                  @ApiParam(value = "初始密码", required = true) @RequestParam(value = "password") String psw) {
        // 参数校验
        if (!ValidUtil.isEmail(mail)) {
            return R.fail("请输入正确的邮箱地址");
        }

        // 检查邮箱验证码是否输入正确
        R<String> result = msgClient.validMailCode(this.validMailPhoneReqHandler(mail, mailCode));
        if(!result.isSuccess()) {
            return R.fail(result.getMsg());
        }

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(User::getAccount, mail);
        if(null != userService.getOne(wrapper, false)) {
            return R.fail("邮箱已注册, 请勿重复注册");
        }

        // 设置用户拥有的初级权限
        User user = new User();
        user.setAccount(mail);
        user.setEmail(mail);
        user.setPassword(DigestUtil.encrypt(psw));
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userService.saveOrUpdate(user, wrapper);
        return R.success("注册成功！");
    }

    @PostMapping("update-psw")
    @ApiOperation("更新密码")
    @BeforeAuth(RoleConstant.ADMINISTRATOR)
    public R<String> updatePsw(@RequestParam("ids") String ids) {
        return R.status(userService.update(new LambdaUpdateWrapper<User>()
                .set(User::getPassword, DigestUtil.encrypt(userProperties.getPassword()))
                .in(User::getId, Func.toArray(ids))));
    }

    @PostMapping("user/test")
    @ApiOperation("测试")
    public R<List<User>> tempBoolean(HttpServletRequest request, @RequestParam Map<String, Object> param) {
        systemClient.tempBoolean();
        List<User> users = CacheUtil.getObj("test:key", 300L,
                (list) -> null != list && list.size() > 0, () -> userService.list(), new TypeReference<List<User>>() {});
        return R.data(users);
    }

    private ValidMailPhoneReq validMailPhoneReqHandler(String mailPhone, String code) {
        ValidMailPhoneReq validMailPhoneReq = new ValidMailPhoneReq();
        validMailPhoneReq.setMailPhone(mailPhone);
        validMailPhoneReq.setCode(code);
        validMailPhoneReq.setClientIP(WebUtil.getIp());
        validMailPhoneReq.setType(MailPhoneType.REGISTER.code());
        return validMailPhoneReq;
    }

    @PostMapping("user-info")
    @ApiOperation("获取用户信息")
    public R<UserVO> userInfo(CloudUser cloudUser) {
        UserVO vo = BeanUtil.copy(userService.getById(cloudUser.getUserId()), UserVO.class);
        // 获取用户当前的权限标识
        vo.setPerms(SystemCache.getRolePerms(vo.getRoleId()));
        // 用户拥有的权限
        vo.setRoles(SystemCache.getRoleAlias(vo.getRoleId()));
        return R.data(vo);
    }

    @PostMapping("user-setting")
    @ApiOperation("获取用户配置")
    public R<UserSetting> userSetting(CloudUser user) {
        return R.data(new UserSetting());
    }

}
